package com.citywithincity.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.citywithincity.db.Page;


/**
 * 发送json
 * 
 * @author Randy
 * 
 */
public class JsonUtil {
	private static ObjectMapper mapper = new ObjectMapper();
	

	public static String toRedisStringResult(Collection<String> list){
		StringBuilder sb = new StringBuilder("{\"flag\":0,\"result\":[");
		boolean first = true;
		for (String string : list) {
			if(first){
				first = false;
			}else{
				sb.append(',');
			}
			sb.append(string);
		}
		
		sb.append("]}");
		return sb.toString();
	}
	

	/**
	 * 错误信息，一般以弹出框形式出现,比较强烈
	 * @param errorMsg
	 * @return
	 */
	
	public static String alert(String errorMsg) {
		StringBuilder sb = new StringBuilder("{\"flag\":-1,\"result\":\"");
		sb.append(errorMsg);
		sb.append("\"}");
		return sb.toString();
	}
	
	
	public static String io(String errorMsg){
		StringBuilder sb = new StringBuilder("{\"flag\":-1,\"result\":\"");
		sb.append(errorMsg);
		sb.append("\"}");
		return sb.toString();
	}
	
	/**
	 * 服务超时，需要客户端重发
	 * @return
	 */
	public static String serviceTimeout(){
		return "{\"flag\":-3,\"result\":\"ServiceTimeout\"}";
	}
	
	
	
	/**
	 * 错误信息，一般以toast形式出现
	 * @param errorMsg
	 * @return
	 */
	@Deprecated
	public static String error(String errorMsg) {
		StringBuilder sb = new StringBuilder("{\"flag\":-1,\"result\":\"");
		sb.append(errorMsg);
		sb.append("\"}");
		return sb.toString();
	}
	
	public static Map<String, Object> errorMap(String errorMsg) {
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("flag", -1);
		data.put("result", errorMsg);
		return data;
	}
	
	/**
	 * @param value
	 * @return
	 */
	public static String success(Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("flag", 0);
		//兼容
		if(value instanceof Page){
			Page<?> page = (Page<?>)value;
			page.toMap(map);
			return toJson(map);
		}else{
			map.put("result", value);
			return toJson(map);
		}
		
	}
	
	public static Map<String, Object> successMap(Object value){
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("flag", 0);
		map.put("result", value);
		return map;
	}
	
	
	public static String raw(int flag,Object result){
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("flag", flag);
		map.put("result", result);
		return toJson(map);
	}
	
	/**
	 * 分页
	 * @param page
	 * @return
	 */
	public static <T> String page(Page<T> page){
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("result", page.getList());
		map.put("page", page.getPage());
		map.put("total", page.getTotalPages());
		map.put("totalRows", page.getTotalRows());
		map.put("flag", 0);
		return toJson(map);
	}
	
	public static String page(int page,int total,int totalRows,Collection<String> set){
		//这里直接输出json
		StringBuilder sb = new StringBuilder();
		sb.append("{\"flag\":0,\"page\":").append(page)
		.append(",\"total\":").append(total)
		.append(",\"totalRows\":").append(totalRows)
		.append(",\"result\":[");
		CollectionUtil.join(sb, set, ",");
		sb.append("]}");
		return sb.toString();
	}
	
	
	public static final String FLAG = "flag";
	public static final String RESULT = "result";

	// 服务器错误
	public static final int ErrCode_Service = 1;
	// 服务器端数据库操作失败
	public static final int ErrCode_Database = 2;
	// 用户没有操作这个接口的权限
	public static final int ErrCode_NoRight = 3;
	// 客户端提交的参数错误
	public static final int ErrCode_Param = 4;
	// 客户端提交的参数错误
	public static final int ErrCode_Json_Format = 5;
	// 客户端提交的参数错误
	public static final int ErrCode_Null_Value = 6;
	// 用户没有登录，但是本接口要求用户登录
	public static final int ErrCode_NotLogin = 7;
	// 客户端提交的数据版本与服务器端的数据版本不一致
	public static final int ErrCode_SameVersion = 8;
	// 签名失败，需要下载客户端密钥
	public static final int ErrCode_RequireAccessToken = 9;
	// 签名失败
	public static final int ErrCode_SignError = 10;
	// 错误地址
	public static final int ErrCode_UrlError = 11;
	//商户id错误
	public static final int ErrCode_BusinessID = 12;
	//商户状态错误
	public static final int ErrCode_BusinessStatus = 13;
	//请求时间和服务器时间相差太多(5分钟)
	private static final int ErrCode_RequestTime = 14;
	//用户登录信息已经过期或无效，请求客户端重新登录
	private static final int ErrCode_LoginInvalidate = 15;


	/**
	 * 格式验证需要
	 */
	public static final String VERIFY = "verify";
	public static final String CONTENT = "content";
	public static final String DEVICE_ID = "deviceID";
	public static final String PUSH_ID = "pushID";
	// 未登录错误
	public static final String ERROR_NOT_LOGIN_JSON;
	// url错误
	public static final String ERROR_URL_JSON;
	//需要token
	public static final String ERROR_ACCESS_TOKEN;
	//需要token
	public static final String ERROR_NULL_TOKEN;

	// 参数错误
	public static final String ERROR_PARAM_JSON;
	// 服务器错误
	public static final String ERROR_SERVER_JSON;
	// 签名失败
	public static final String ERROR_SIGN_JSON;
	// 需要加密
	public static final String REQUIRE_ACCESS_TOKEN;
	//商户编号错误
	public static final String ERROR_BUSINESS;
	//商户状态错误
	public static final String ERROR_BUSINESS_STATUS;
	//请求时间错误
	public static final String ERROR_REQUEST_TIME;
	
	public static final String ERROR_LOGIN_INVALIDATE;
	
	public static final String JSON_SUCCESS_TRUE;
	public static final int FlagSuccess = 0;
	static {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_Param);
		//map.put(RESULT, "ErrCode_Param");
		ERROR_PARAM_JSON = toJson(map);

		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_Service);
		//map.put(RESULT, "ErrCode_Service");
		ERROR_SERVER_JSON = toJson(map);

		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_SignError);
		//	map.put(RESULT, "ErrCode_SignError");
		ERROR_SIGN_JSON = toJson(map);

		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_RequireAccessToken);
		//map.put(RESULT, "ErrCode_RequireAccessToken");
		REQUIRE_ACCESS_TOKEN = toJson(map);

		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_UrlError);
		//map.put(RESULT, "ErrCode_UrlError");
		ERROR_URL_JSON = toJson(map);

		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_NotLogin);
		//map.put(RESULT, "ErrCode_NotLogin");
		ERROR_NOT_LOGIN_JSON = toJson(map);
		
		
		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_RequireAccessToken);
		//map.put(RESULT, "ErrCode_NullToken");
		ERROR_NULL_TOKEN = toJson(map);
		
		
		
		
		map = new HashMap<String, Object>();
		map.put(FLAG, 0);
		map.put(RESULT, true);
		JSON_SUCCESS_TRUE = toJson(map);
		
		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_BusinessID);
		//map.put(RESULT, "ErrCode_BusinessID");
		ERROR_BUSINESS = toJson(map);
		
		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_LoginInvalidate);
		//map.put(RESULT, "ErrCode_LoginInvalidate");
		ERROR_LOGIN_INVALIDATE = toJson(map);
		
		
		
		
		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_BusinessStatus);
		//map.put(RESULT, "ErrCode_BusinessStatus");
		ERROR_BUSINESS_STATUS = toJson(map);
		
		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_RequestTime);
		//map.put(RESULT, "ErrCode_RequestTime");
		ERROR_REQUEST_TIME = toJson(map);
		
		
		map = new HashMap<String, Object>();
		map.put(FLAG, ErrCode_RequireAccessToken);
		//map.put(RESULT, "ErrCode_RequireAccessToken");
		ERROR_ACCESS_TOKEN = toJson(map);
		
	}
	

	
	/**
	 * 
	 * @param object
	 * @return
	 */
	public static String toJson(Object object) {
		try {
			return mapper.writeValueAsString(object);
		} catch (Exception e){
			throw new RuntimeException(e);
		}
	}
	
	
	@SuppressWarnings("unchecked")
	public static Map<String, Object> read(String line) throws  IOException {
		return mapper.readValue(line, Map.class);
	}
	
	@SuppressWarnings("rawtypes")
	public static List ReadListener(String line) throws IOException{
		return mapper.readValue(line, List.class);
	}
	
	@SuppressWarnings("unchecked")
	public static Map<String, Object> read(Reader reader) throws  IOException {
		return mapper.readValue(reader, Map.class);
	}
	@SuppressWarnings("unchecked")
	public static Map<String, Object> read(InputStream inputStream) throws  IOException{
		return mapper.readValue(inputStream, Map.class);
	}
	public static Object readToObject(InputStream inputStream) throws  IOException{
		return mapper.readValue(inputStream, Object.class);
	}
	
	@SuppressWarnings("unchecked")
	public static Map<String, Object> read(byte[] buffer) throws  IOException {
		return mapper.readValue(buffer, Map.class);
	}
	
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> readList(String content) throws  IOException{
		return mapper.readValue(content, List.class);
	}
	
	public static void toJsonAndClose(OutputStream outputStream, Map<String, Object> data) throws IOException {
		try {
			mapper.writeValue(outputStream, data);
		} catch (JsonGenerationException e) {
			throw new RuntimeException(e);
		} catch (JsonMappingException e) {
			throw new RuntimeException(e);
		}finally {
			IoUtil.close(outputStream);
		}
	}
	public static void toJsonAndClose(HttpServletResponse response, Map<String, Object> data) throws IOException {
		OutputStream outputStream = response.getOutputStream();
		toJsonAndClose(outputStream, data);
	}


	public static ObjectMapper getMapper() {
		return mapper;
	}


	public static <T> T read(String content, Class<T> classOfT) throws IOException {
		try {
			return mapper.readValue(content, classOfT);
		} catch (JsonParseException e) {
			throw new IOException(e);
		} catch (JsonMappingException e) {
			throw new IOException(e);
		} 
	}


	

}
